package com.bjt.wms.sys.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.bjt.common.config.paragetter.BasePageRequest;
import com.bjt.wms.sys.model.DeliverySheet;
import com.bjt.wms.sys.model.FlowDetail;
import com.bjt.utils.R;
import com.bjt.wms.sys.model.Stock;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.Tx;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 耗材库存状态流转服务
 *
 * @author WenbinJi
 */
public class FLowDetailService {
    private Log logger = Log.getLog(this.getClass());

    @Inject
    private MaterialService materialService;

    @Inject
    private DeliverySheetService deliverySheetService;

    public R queryInboundList(BasePageRequest<FlowDetail> basePageRequest, Kv cond) {
        SqlPara sqlPara = Db.getSqlPara("sys.flowDetail.queryInboundList", Kv.by("cond", cond));

        Page<Record> pageData = Db.paginate(basePageRequest.getPage(), basePageRequest.getLimit(), sqlPara);
        return R.ok().put("data", pageData.getList()).put("count", pageData.getTotalRow());
    }

    public R queryOutboundList(BasePageRequest<FlowDetail> basePageRequest, Kv cond) {
        SqlPara sqlPara = Db.getSqlPara("sys.flowDetail.queryOutboundList", Kv.by("cond", cond));

        Page<Record> pageData = Db.paginate(basePageRequest.getPage(), basePageRequest.getLimit(), sqlPara);
        return R.ok().put("data", pageData.getList()).put("count", pageData.getTotalRow());
    }

    /**
     * 执行耗材出入库事务
     */
    @Before(Tx.class)
    public Ret runInOutboud(JSONObject jsonObject, List<String> paths) {
        List<String> rfidList = jsonObject.getJSONArray("material_rfids").toJavaList(String.class);//获取出入库rfid集合
        int warehouseId = jsonObject.getIntValue("warehouse_id");//获取仓库ID

        String type;
        int deliverySheetId = 0;
        if (jsonObject.containsKey("delivery_sheet_id")) {
            type = "inbound";//入库

            deliverySheetId = jsonObject.getIntValue("delivery_sheet_id");
            DeliverySheet deliverySheet = DeliverySheet.dao.findById(deliverySheetId);
            if (deliverySheet.getState() == "已完成") {
                return Ret.fail("msg", "该配货单已完成，请勿重复入库");
            }

            deliverySheetService.completeDeliverySheet(deliverySheetId);//变更配货单状态
            logger.info("入库单号 " + deliverySheet.getCode() + " 已完成");
        } else {
            type = "outbound";//出库
        }

        Map<String, Integer> idMap = new HashMap<>();//RFID-ID键值对
        Map<Integer, Integer> quantityMap = new HashMap<>();//ID-数量键值对
        List<FlowDetail> flowDetailList = new ArrayList<>();//批量新增耗材出入库记录
        for (String rfid : rfidList) {
            String key = rfid.substring(0, 4);
            if (!idMap.containsKey(key)) {
                idMap.put(key, materialService.getMaterialIdByRfid(key));
            }

            int material_id = idMap.get(key);

            if (quantityMap.containsKey(material_id)) {
                quantityMap.put(material_id, quantityMap.get(material_id) + 1);//增加数量
            } else {
                quantityMap.put(material_id, 1);
            }

            FlowDetail flowDetail = new FlowDetail();
            flowDetail.setWarehouseId(warehouseId);
            flowDetail.setMaterialId(material_id);
            flowDetail.setRfid(rfid);
            flowDetail.setEmployeeHandlerId(jsonObject.getInteger("employee_handler_id"));
            flowDetail.setCreateTime(DateUtil.date().toString("yyyy-MM-dd HH:mm:ss"));
            flowDetail.setPhotoPath(StringUtils.join(paths, ","));

            //入库需要填入入库单ID 和 检查人ID
            if (type == "inbound") {
                flowDetail.setSheetId(deliverySheetId);
                flowDetail.setEmployeeAssessorId(jsonObject.getInteger("employee_assessor_id"));
            }
            flowDetailList.add(flowDetail);
        }
        Db.batchSave(flowDetailList, 100);//批量插入出入库记录

        List<Stock> stockList = new ArrayList<>();
        for (int material_id : quantityMap.keySet()) {
            Stock stock = Stock.dao.findFirst("select * from stock where material_id=" + material_id);
            if (type == "inbound") {
                stock.setQuantityIn(stock.getQuantityIn() + quantityMap.get(material_id));
            } else {
                stock.setQuantityOut(stock.getQuantityOut() + quantityMap.get(material_id));
                stock.setLastOutboundEmployeeId(jsonObject.getIntValue("employee_handler_id"));
                stock.setLastOutboundTime(DateUtil.date().toString("yyyy-MM-dd HH:mm:ss"));
            }
            stockList.add(stock);
        }
        Db.batchUpdate(stockList, 100); //批量变更库存数量
        return Ret.ok();
    }
}
